package com.redlion.weapon;

import org.andengine.entity.sprite.AnimatedSprite.IAnimationListener;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.util.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.redlion.Game;
import com.redlion.object.Planet;

public class PlayerWeapon extends AbstractAnimationWeapon implements IPlayerWeapon {

	private static final float SHOT_OFFSET = 50;
	public OnFireListener shotListener;
	public IdHolder mIdHolder;
	public Vector2 dir;
	public Vector2 rotationVector;

	public PlayerWeapon(Vector2 position, ITiledTextureRegion textureRegion, FixtureDef fixDef) {
		super(position, textureRegion, fixDef);
		hide();
	}

	public PlayerWeapon(Vector2 position, ITiledTextureRegion textureRegion) {
		super(position, textureRegion);
	}

	@Override
	protected void createAnimation() {

	}

	public void alignToPlanet(Planet p, float offset) {
		sprite.setPosition(p.centerX + offset - (sprite.getWidth() / 2), p.centerY - (sprite.getHeight() / 2));
		sprite.setRotationCenterX(-offset + (sprite.getWidth() / 2));
	}

	@Override
	protected void createAnimation(float px, float py) {
		sprite = new AnimatedSprite(px - (mTiledTextureRegion.getWidth() / 2), py - (mTiledTextureRegion.getHeight() / 2),
				mTiledTextureRegion, Game.gameActivity.getVertexBufferObjectManager());
	}

	@Override
	protected void createBody(FixtureDef fixtureDef) {
		body = PhysicsFactory.createCircleBody(Game.mPhysicsWorld, sprite, BodyType.DynamicBody, fixtureDef);
		body.setUserData(getClass());
	}

	@Override
	public void setFireListener(OnFireListener listener) {
		this.shotListener = listener;
	}

	@Override
	public void fire() {
		if (shotListener != null) {
			shotListener.firePlayerWeapon(this);
		}
	}

	public void update(float delta) {
	}

	@Override
	public IAnimationListener getAnimationListener() {
		return new IAnimationListener() {

			@Override
			public void onAnimationStarted(AnimatedSprite pAnimatedSprite, int pInitialLoopCount) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationLoopFinished(AnimatedSprite pAnimatedSprite, int pRemainingLoopCount, int pInitialLoopCount) {
				fire();
			}

			@Override
			public void onAnimationFrameChanged(AnimatedSprite pAnimatedSprite, int pOldFrameIndex, int pNewFrameIndex) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationFinished(AnimatedSprite pAnimatedSprite) {
				// TODO Auto-generated method stub

			}
		};
	}

	public Vector2 getShotOrigin(boolean update) {
		if (dir == null || update) {
			float degAngle = MathUtils.degToRad(sprite.getRotation());
			dir = new Vector2((float) Math.cos(degAngle), (float) Math.sin(degAngle)).nor();
		}
		return Game.planet.center.cpy().add(dir.cpy().mul(Game.planet.raduis + SHOT_OFFSET));
	}

	public void hide() {
		sprite.setIgnoreUpdate(true);
		sprite.setVisible(false);
	}

	// @Override
	// public int getWeaponID() {
	// if (mIdHolder != null)
	// return mIdHolder.weaponIndex;
	// return -1;
	// }

	// @Override
	// public int getUpgradeID() {
	// if (mIdHolder != null)
	// return mIdHolder.upgradeIndex;
	// return -1;
	// }

	// @Override
	// public void updateAnimation(Upgrade upgrade, int[] textureIndices) {
	// sprite.setIgnoreUpdate(false);
	// sprite.setVisible(true);
	// animate(upgrade.delay, textureIndices);
	// }

	// @Override
	// public void setIdHolder(IdHolder userData) {
	// mIdHolder = userData;
	// }

	/**
	 * updates the rotation of the weapon
	 * 
	 * @param rotationVector
	 *            the normalized vector shows away from the planet-center.
	 */
	public void updateRotation(Vector2 rotationVector) {
		this.rotationVector = rotationVector;
		float radAngle = MathUtils.atan2(rotationVector.y, rotationVector.x);
		this.sprite.setRotation(MathUtils.radToDeg(radAngle));
	}

	@Override
	public void updateAnimation(Upgrade upgrade, int[] textureIndices) {

	}

	public void stopAnimationAt(int i) {
		this.sprite.stopAnimation(i);
	}

}
